package com.elite.groovy.kh;

import com.ciphergateway.crypto.CGCipher;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Locale;

/**
 * @projectName: ngsapitask-tp2.6
 * @package: com.elite.groovy.kh
 * @className: GMSMUtils
 * @author: LiJT
 * @description: TODO
 * @date: 2024-10-25 10:18
 * @version: 1.0
 */
public class GMSMUtils {
    private static final Log log = LogFactory.getLog(GMSMUtils.class);
    private static byte[] keys = new byte[]{-2, -1, -23, -110, -122, 101, 115, 28, 109, 106, -113, -108, 103, 48, -125, 8};
    private static byte[] iv = new byte[]{-103, -86, 62, 104, -19, -127, 115, -96, -18, -48, 102, -124, -18, -48, 102, -124};
    private static byte[] aad = new byte[]{77, 35, -61, -50, -61, 52, -76, -101, -37, 55, 12, 67, 127, -20, 120, -34};
    private static byte[] cipher;
    private static byte[] plain;

    public GMSMUtils() {
    }

    public static void main(String[] args) {
        String mobile = "18675571253abc";
        String encc = encrypt(mobile, "");
        System.out.println(encc);
        String dncc = decrypt(encc, "");
        System.out.println(dncc);
    }

    public static String decrypt(String encrypted, String key) {
        return encrypted != null && encrypted.length() != 0 ? decrypt("sm4", "cbc", encrypted, key) : "";
    }

    public static String encrypt(String encrypted, String key) {
        return encrypted != null && encrypted.length() != 0 ? encrypt("sm4", "cbc", encrypted, key) : "";
    }

    public static String encrypt(String ciphername, String funciton, String input, String key) {
        CGCipher sm4 = CGCipher.getInstance(ciphername, funciton);
        byte[] inputByte = toByteArray(input);
        log.debug("SM4待加密内容：" + inputByte.length + " bytes message:" + toHexString(inputByte));
        cipher = sm4.sm4_encrypt(1, inputByte, keys, iv);
        if (cipher == null) {
            log.debug("SM4 Encrypt Faild");
            return "";
        } else {
            String message_enc = toHexString(cipher).toUpperCase(Locale.ROOT);
            log.debug("SM4加密数据后字符串：" + message_enc);
            return message_enc;
        }
    }

    public static String decrypt(String ciphername, String funciton, String encrypted, String key) {
        CGCipher sm4 = CGCipher.getInstance(ciphername, funciton);
        log.debug("SM4待解密字符串：" + encrypted);
        byte[] cipherByte = toByteArray(encrypted);
        plain = sm4.sm4_decrypt(1, cipherByte, keys, iv);
        if (plain == null) {
            log.debug("SM4 Decrypt Faild");
            return "";
        } else {
            String message_dnc = toHexString(plain);
            log.debug("SM4解密数据后字符串：" + plain.length + " bytes plain:" + message_dnc);
            return message_dnc;
        }
    }

    public static byte[] toByteArray(String hexString) {
        if (hexString != null && hexString.length() > 0) {
            hexString = hexString.toLowerCase();
            byte[] byteArray = new byte[hexString.length() / 2];
            int k = 0;

            for (int i = 0; i < byteArray.length; ++i) {
                byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 255);
                byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 255);
                byteArray[i] = (byte) (high << 4 | low);
                k += 2;
            }

            return byteArray;
        } else {
            throw new IllegalArgumentException("this hexString must not be empty");
        }
    }

    public static String toHexString(byte[] byteArray) {
        if (byteArray != null && byteArray.length >= 1) {
            StringBuilder hexString = new StringBuilder();

            for (int i = 0; i < byteArray.length; ++i) {
                if ((byteArray[i] & 255) < 16) {
                    hexString.append("0");
                }

                hexString.append(Integer.toHexString(255 & byteArray[i]));
            }

            return hexString.toString().toLowerCase();
        } else {
            throw new IllegalArgumentException("this byteArray must not be null or empty");
        }
    }
}